Welcome to Hands on deep learning!

02.01.02. 运算符

我们的兴趣不仅限于读取数据和写入数据。 我们想在这些数据上执行数学运算,其中最简单且最有用的操作是按元素(elementwise)运算。 它们将标准标量运算符应用于数组的每个元素。 对于将两个数组作为输入的函数,按元素运算将二元运算符应用于两个数组中的每对位置对应的元素。 我们可以基于任何从标量到标量的函数来创建按元素函数。

在数学表示法中,我们将通过符号\(f: \mathbb{R} \rightarrow \mathbb{R}\) 来表示一元标量运算符(只接收一个输入)。 这意味着该函数从任何实数(\(\mathbb{R}\))映射到另一个实数。 同样,我们通过符号\(f: \mathbb{R}, \mathbb{R} \rightarrow \mathbb{R}\) 表示二元标量运算符,这意味着该函数接收两个输入,并产生一个输出。 给定同一形状的任意两个向量\(\mathbf{u}\)和\(\mathbf{v}\)和二元运算符\(f\), 我们可以得到向量\(\mathbf{c} = F(\mathbf{u},\mathbf{v})\)。 具体计算方法是\(c_i \gets f(u_i, v_i)\), 其中\(c_i\)、\(u_i\)和\(v_i\)分别是向量\(\mathbf{c}\)、\(\mathbf{u}\)和\(\mathbf{v}\)中的元素。 在这里,我们通过将标量函数升级为按元素向量运算来生成向量值 \(F: \mathbb{R}^d, \mathbb{R}^d \rightarrow \mathbb{R}^d\)。

对于任意具有相同形状的张量, 常见的标准算术运算符(+、-、*、/和**)都可以被升级为按元素运算。 我们可以在同一形状的任意两个张量上调用按元素操作。 在下面的例子中,我们使用逗号来表示一个具有5个元素的元组,其中每个元素都是按元素操作的结果。

import torch

x = torch.tensor([1.0, 2, 4, 8])

y = torch.tensor([2, 2, 2, 2])

a=x + y

b=x - y

c=x * y

d=x / y

e=x ** y # **运算符是求幂运算

print(a,"\n",

b,"\n",

c,"\n",

d,"\n"

,e)

返回值:

tensor([ 3., 4., 6., 10.])

tensor([-1., 0., 2., 6.])

tensor([ 2., 4., 8., 16.])

tensor([0.5000, 1.0000, 2.0000, 4.0000])

tensor([ 1., 4., 16., 64.])

“按元素”方式可以应用更多的计算,包括像求幂这样的一元运算符。

import torch

x = torch.tensor([1.0, 2, 4, 8])

a=torch.exp(x) #是 **指数函数**;(Exponential Function)的缩写,它表示计算张量中每个元素的自然指数(e的x次方)

print(a)

返回值:

tensor([2.7183e+00, 7.3891e+00, 5.4598e+01, 2.9810e+03])

除了按元素计算外,我们还可以执行线性代数运算,包括向量点积和矩阵乘法。 我们将在 2.3节中解释线性代数的重点内容。

我们也可以把多个张量连结(concatenate)在一起, 把它们端对端地叠起来形成一个更大的张量。 我们只需要提供张量列表,并给出沿哪个轴连结。 下面的例子分别演示了当我们沿行(轴-0,形状的第一个元素) 和按列(轴-1,形状的第二个元素)连结两个矩阵时,会发生什么情况。 我们可以看到,第一个输出张量的轴-0长度(\(6\))是两个输入张量轴-0长度的总和(\(3 + 3\)); 第二个输出张量的轴-1长度(\(8\))是两个输入张量轴-1长度的总和(\(4 + 4\))。

import torch

X = torch.arange(12, dtype=torch.float32).reshape((3,4))

Y = torch.tensor([[2.0, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])

a=torch.cat((X, Y), dim=0), torch.cat((X, Y), dim=1)

print(a)

返回值:

(tensor([[ 0., 1., 2., 3.],

[ 4., 5., 6., 7.],

[ 8., 9., 10., 11.],

[ 2., 1., 4., 3.],

[ 1., 2., 3., 4.],

[ 4., 3., 2., 1.]]), tensor([[ 0., 1., 2., 3., 2., 1., 4., 3.],

[ 4., 5., 6., 7., 1., 2., 3., 4.],

[ 8., 9., 10., 11., 4., 3., 2., 1.]]))

有时,我们想通过逻辑运算符构建二元张量。 以X == Y为例: 对于每个位置,如果X和Y在该位置相等,则新张量中相应项的值为1。 这意味着逻辑语句X == Y在该位置处为真,否则该位置为0。

import torch

X = torch.arange(12, dtype=torch.float32).reshape((3,4))

Y = torch.tensor([[2.0, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])

a=(X == Y)

print(a)

返回值:

tensor([[False, True, False, True],

[False, False, False, False],

[False, False, False, False]])

对张量中的所有元素进行求和,会产生一个单元素张量。

import torch

X = torch.arange(12, dtype=torch.float32).reshape((3,4))

a=X.sum()

print(a)

返回值:

tensor(66.)